/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*-  */
/*
 * catchit
 * Copyright (C) 2013 Ryan Grinkewitz <graphite@Toto>
 * 
 */

#include "display-manager.h"
#include <string>
#include <sstream>
#include <iostream>

DisplayManager* DisplayManager::displayManagerInstance = NULL; 
	 
DisplayManager* DisplayManager::getInstance()
{
	if (!displayManagerInstance){ 
		displayManagerInstance = new DisplayManager;
	}
	
	return displayManagerInstance;
}

DisplayManager::DisplayManager(){
	initialize();
	
	spriteManager = new SpriteManager();
	
	spriteManager->loadSpriteSheet ("sprites.png", 32, 2);

	font = TTF_OpenFont( "Super_Mario_Bros.ttf", 14 );
	winFont = TTF_OpenFont( "Super_Mario_Bros.ttf", 24 );
	textColor.r = 0;
	textColor.g = 0;
	textColor.b = 0;
}


//Init function curtesy of www.lazyfoo.net
bool DisplayManager::initialize()
{
	main_screen = NULL;
	font = NULL;
	
    //Initialize all SDL subsystems
    if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
    {
        return false;
    }

    //Set up the screen
    main_screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );

    //If there was an error in setting up the screen
    if( main_screen == NULL )
    {
        return false;
    }

	//Initialize SDL_ttf 
	if( TTF_Init() == -1 ) { 
		return false; 
	}
	
    //Set the window caption
    SDL_WM_SetCaption( "CatchIt", NULL );

	
    //If everything initialized fine
    return true;
}

void DisplayManager::updateDisplay(GameState* currentState){
	if(currentState != NULL)
	{
		//Fill the screen white
		 SDL_FillRect( main_screen, &main_screen->clip_rect, 
		              SDL_MapRGB( main_screen->format, 0xb1, 0xcc, 0xf2 ) );

		int game_position = currentState->getGamePosition();

		//Apply the platforms that are visible
		//Platform vertical separation is 32 pixels from
		//bottom of one to bottom of next
		// level 0 will be at game position 0
		// Game position will be updated by state manager
		//Therefore game_position/32 gives the lower
		//most level currently displayed and the next 19 will
		//be displayed as well. So:
		int lower_level_index = game_position/32;
		
			
		for(int i = lower_level_index;
		    i < lower_level_index + 20 && i < GAME_SIZE
		    ; i++){
				Level* level = currentState->getLevel (i);
				displayLevel(level);
		}

		//Display the computer
		Computer* computer = currentState->getComputer();
		spriteManager->displaySprite (computer->getSpriteId(), 
		                              computer->getXPosition(),
		                              computer->getYPosition(),
			                          main_screen);		
		
		//Display the player
		Player* player = currentState->getPlayer();		
		spriteManager->displaySprite (player->getSpriteId(), 
		                              player->getXPosition(),
		                              player->getYPosition(),
			                          main_screen);
			

		displayScores(player, computer);

		if(player->getIsWinner()){
			displayWin(player);
		}else if(computer->getIsWinner()){
			displayWin(computer);
		}
		
		SDL_Flip( main_screen );
	}	
}

void DisplayManager::displayLevel(Level* level){

//	int screen_y = (game_position%32 + visible_level*32) - 64;

	for(int i = 0; i < LEVEL_SIZE; i++){
		Platform* platform = level->getPlatform (i);
		if(platform != NULL){
			int* spriteIds = platform->getSpriteIds();
		//	spriteManager->displaySprite (spriteIds[0], i*64, screen_y,
		//	                              main_screen);
		//	spriteManager->displaySprite (spriteIds[1], i*64 + 32, screen_y,
		//	                              main_screen);

			spriteManager->displaySprite (spriteIds[0], i*64, level->getLevelYPosition (),
			                              main_screen);
			spriteManager->displaySprite (spriteIds[1], i*64 + 32, level->getLevelYPosition (),
			                              main_screen);			
			
		}
	}
}

void DisplayManager::displayScores(Jumper* player1, Jumper* player2){

	std::string player1String, player2String;
	std::stringstream player1Score, player2Score;
	player1Score << player1->getScore();
	player2Score << player2->getScore();	

	player1String = "Player:  " + player1Score.str();
	player2String = "Computer:  " + player2Score.str();
	SDL_Surface* player1Text = TTF_RenderText_Solid( font, player1String.c_str(), textColor ); 
	SDL_Surface* player2Text = TTF_RenderText_Solid( font, player2String.c_str(), textColor ); 

	SDL_Rect player1StringPosition;
	SDL_Rect player2StringPosition;
	
	player1StringPosition.x = 15;
	player1StringPosition.y = 40;
	player2StringPosition.x = 180;
	player2StringPosition.y = 40;

	SDL_BlitSurface(player1Text, NULL, main_screen,
	                &player1StringPosition);
	SDL_BlitSurface(player2Text, NULL, main_screen,
	                &player2StringPosition);	

	SDL_FreeSurface(player1Text);
	SDL_FreeSurface(player2Text);	

}

void DisplayManager::displayWin(Jumper* player){
	std::string playerString;

	if(player->getIsPlayer ()){
		playerString = "Player Wins!";
	}else{
		playerString = "Computer Wins!";
	}

	SDL_Surface* playerText = TTF_RenderText_Solid( winFont, 
	                                                playerString.c_str(), 
	                                                textColor ); 
	SDL_Rect playerStringPosition;
	
	playerStringPosition.x = SCREEN_WIDTH/2 - 90;
	playerStringPosition.y = SCREEN_HEIGHT/2;
		
	SDL_BlitSurface(playerText, NULL, main_screen,
	                &playerStringPosition);
	SDL_FreeSurface(playerText);
}